package i18n

// Localizer i18n本地化器，封装语言匹配和回退逻辑
type Localizer interface {
	// T 翻译方法，使用默认语言包管理器的默认语言本地化器进行查询翻译
	//   - 如果找不到，否则返回原始 key 字符串
	T(key string, args ...any) string
	// Bundle 获取本地化器绑定的语言包管理器
	Bundle() *Bundle
	// LangName 获取实际支持的语言名称
	LangName() string
	// String 实现 fmt.Stringer 接口，返回实际支持的语言名称
	String() string
}

type localize struct {
	bundle   *Bundle // 本地化器绑定的语言包管理器，用于查找翻译消息
	langName string  // 实际支持的语言名称，例如：zh-CN, en-US 等
}

// NewLocalizer 使用默认 Bundle 管理器创建本地化器，解析用户接受的语言
// 	 - 支持精确匹配明确的语言名称，例如：zh zh-CN zh-Hans en en-US 等简短格式的语言标签
// 	 - 支持最佳匹配来自 HTTP Accept-Language 头部格式的语言标签列表，例如：
// 	 - zh;q=0.8,en;q=0.5,en-US;q=0.3
// 	 - zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
func NewLocalizer(acceptedLangs ...string) Localizer {
	return GetDefaultBundle().NewLocalizer(acceptedLangs...)
}

// NewLocalizer 创建本地化器，解析用户接受的语言
// 	 - 支持精确匹配明确的语言名称，例如：zh zh-CN zh-Hans en en-US 等简短格式的语言标签
// 	 - 支持最佳匹配来自 HTTP Accept-Language 头部格式的语言标签列表，例如：
// 	 - zh;q=0.8,en;q=0.5,en-US;q=0.3
// 	 - zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
func (b *Bundle) NewLocalizer(acceptedLangs ...string) Localizer {
	// 通过 Bundle.supportedLangs 解析用户接受的语言
	if name, ok := b.supportedLangs.MatchStrings(acceptedLangs...); ok {
		return b.localizes[name]
	}
	// 全部失败后, 用默认语言作为支持的回退语言
	if b.supportedLangs.HasDefault() {
		return b.localizes[b.supportedLangs.GetDefaultName()]
	}
	// 没有任何语言匹配也没有默认语言，返回空本地化器
	return &localize{bundle: b}
}

// T 翻译方法，使用默认语言包管理器的默认语言本地化器进行查询翻译
//   - 如果找不到，否则返回原始 key 字符串
func T(key string, args ...any) string {
	return GetDefaultLocalizer().T(key, args...)
}

// T 翻译方法，依据 Localizer 语言包进行查询翻译
//   - 如果找不到，则尝试回退到默认语言包, 否则返回原始 key 字符串
func (l *localize) T(key string, args ...any) string {
	parseKey, err := ParseKey(key)
	if err != nil {
		// key 无效，返回原始key
		return key
	}
	// 通过受支持的语言包查找翻译消息
	if msg, exists := l.bundle.getOneMessage(l.langName, parseKey); exists {
		return msg.Display(args...)
	}
	// 查找默认语言翻译（回退处理）
	if l.bundle.supportedLangs.HasDefault() &&
		l.langName != l.bundle.supportedLangs.GetDefaultName() {
		if msg, exists := l.bundle.getOneMessage(l.bundle.supportedLangs.GetDefaultName(), parseKey); exists {
			return msg.Display(args...)
		}
	}
	// 未找到翻译，返回 parseKey
	return parseKey
}

// Bundle 获取本地化器绑定的语言包管理器
func (l *localize) Bundle() *Bundle {
	return l.bundle
}

// LangName 获取实际支持的语言名称
func (l *localize) LangName() string {
	return l.langName
}

// String 实现 fmt.Stringer 接口，返回实际支持的语言名称
func (l *localize) String() string {
	return l.langName
}
